/*******************************************************************************
 * 版权：北京润尼尔网络科技有限公司，保留所有版权<br>
 * 版本：v1.0.0<br>
 * 文件：OrthogonalConnectionCreatePolicy.js<br>
 * 日期：2016年9月28日<br>
 * 作者: 王志远<br>
 * 功能：直角连接创建器<br>
 * 
 * 修改记录：<br>
 * 日期 描述 更新功能<br>
 ******************************************************************************/

window.makeNamespace(window,"Rainier.UI.V2");

/**
 * 类型名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy<br>
 * 类型功能：抽象模型<br>
 */
Rainier.UI.V2.OrthogonalConnectionCreatePolicy = draw2d.policy.connection.OrthogonalConnectionCreatePolicy.extend({
	
	NAME : "Rainier.UI.V2.OrthogonalConnectionCreatePolicy",
	
	START_CREATE_STATE : "STATE_CREATE_STATE",	//开始创建状态
	ADD_SEGEMENT_STATE : "ADD_SEGEMENT_STATE",	//添加线段状态
	END_CREATE_STATE   : "END_CREATE_STATE",	//结束创建状态
	ADJUST_VALUE       : 9, 					//自适应值
	JOINT_SENSITIVITY_VALUE  : 4,				//创建节点灵敏度值
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy.init<br>
	 * 函数功能：构造函数<br>
	 * 参数输入:property属性对象<br>
	 * 异常信息：无<br>
	 */
    init: function(attr, setter, getter){
        this._super( attr, setter, getter);
        this.sourcePort = null;
        this.targetPort = null;
        this.segmentList= new draw2d.util.ArrayList();
        
        var _this = this;
        
		//创建连接的三个状态：start、addline和end状态
		this.runState = StateMachine.create({
			  
			initial: 'none',
			  
			error: function(eventName, from, to, args, errorCode, errorMessage) {
			    	return 'event ' + eventName + ' was naughty :- ' + errorMessage;
			},
			
			events: [
			   { name: 'EventStartToEnd', 			from: 'start',    	to: 'end'},
			   { name: 'EventStartToAddJoint',		from: 'start',    	to: 'addjoint'},
			   { name: 'EventStartToAddLine',  		from: 'start',  	to: 'addline'},
			   { name: 'EventAddLineToAddLine',  	from: 'addline',  	to: 'addline'},
			   { name: 'EventAddLineToAddJoint',  	from: 'addline',  	to: 'addjoint'},
			   { name: 'EventAddLineToEnd', 		from: 'addline', 	to: 'end'},
			   { name: 'EventAddLineToCancel',  	from: 'addline',  	to: 'cancel'},
			],
			
			callbacks: {
				
				//处理从添加线段状态到添加节点状态
				onEventAddLineToAddJoint:function(event, from, to, msg) { 
			    	_this.processAddLineToAddJoint(msg);
			    },
				
			    //处理从开始状态到添加节点状态
				onEventStartToAddJoint:function(event, from, to, msg) { 
			    	_this.processStartToAddJoint(msg);
			    },
			    
			    //处理从添加线段状态到取消状态
			    onEventCancel:function(event, from, to, msg) { 
			    	_this.processCancel(msg);
			    },
				
			    //处理从开始状态到结束状态
			    onEventStartToEnd:function(event, from, to, msg) { 
			    	_this.processStartToEnd(msg);
			    },
			    
			    //处理从开始状态到添加线段状态
			    onEventStartToAddLine:function(event, from, to, msg) {
			    	_this.processStartToAddLine(msg);
			    },
			    
			    //处理保持添加连续状态
			    onEventAddLineToAddLine:function(event, from, to, msg){
			    	_this.processKeepAddLine(msg);
			    },
			    
			    //处理从添加连线状态到结束状态
			    onEventAddLineToEnd:function(event, from, to,msg){
			    	_this.processAddLineToEnd(msg);
			    },
		    }
		});
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy.processStartup<br>
	 * 函数功能：处理开始连接<br>
	 * 参数输入：object:{source:port}<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	processStartup : function(args){
		var _this  = this;
		var port   = args.source;
        var canvas = port.getCanvas();
        this.port1 = port;
        this.vertices.add(port.getAbsolutePosition());
        this.beeline = new draw2d.shape.basic.Line({
            start: this.port1.getAbsolutePosition(),
            end: this.port1.getAbsolutePosition(),
            dasharray:"- ",
            color:"#2C70FF"
        });

        this.beeline.hide= function(){
            _this.beeline.setCanvas(null);
        };

        this.beeline.show= function(canvas){
            _this.beeline.setCanvas(canvas);
            _this.beeline.shape.toFront();
        };
        this.beeline.show(canvas);

        this.tempConnection = new draw2d.shape.basic.PolyLine({
            start: this.port1.getAbsolutePosition(),
            end: this.port1.getAbsolutePosition(),
            stroke:2,
            color:"#2C70FF"
        });

        this.tempConnection.hide= function(){
            _this.tempConnection.setCanvas(null);
        };

        this.tempConnection.show= function(canvas){
            _this.tempConnection.setCanvas(canvas);
            _this.tempConnection.shape.toFront();
        };
        this.tempConnection.show(canvas);
        this.tempConnection.setVertices([this.port1.getAbsolutePosition(),this.port1.getAbsolutePosition()]);

        var a= function() {
            _this.tempConnection.shape.animate({"stroke-width" : 2}, 800, b);
        };
        var b=function() {
            _this.tempConnection.shape.animate({"stroke-width":1}, 800, a);
        };
        a();

        canvas.paper.setStart();

        // delete the previews puls if the user press twice on the starting port
        //
        if(this.pulse!==null) {
            this.pulse.remove();
            this.pulse = null;
        }

        var pos = port.getAbsolutePosition();
        this.ripple(pos.x, pos.y, 1);
        this.pulse = canvas.paper.setFinish();
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy.processAddLineToAddJoint<br>
	 * 函数功能：从连线到添加结点状态处理<br>
	 * 参数输入：args：object{source:port}<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	processAddLineToAddJoint : function(args){
		console.log("from addline to add joint:" + args);
	
		try{
			var source 		= args.source;		//源端口
			var targetConn 	= args.connection;	//目标端口
			var mouseX 		= args.x;			//鼠标点击x位置
			var mouseY 		= args.y;			//鼠标点击y位置
			var jointLoc    = this._calculateJointLocation(mouseX,mouseY,targetConn);
			
			var newVertices = new draw2d.util.ArrayList();
			this._toSegmentListByTargetPortLocation(this.vertices,jointLoc,this.segmentList,newVertices);
			this.vertices = newVertices;
			this.tempConnection.setVertices(this.vertices);
			
			var cmd = new Rainier.UI.V2.CommandAddJoint();
			cmd.setSourcePort(source);
			cmd.setTargetConnection(targetConn);
			cmd.setJointLocation(jointLoc);
			cmd.setVertices(this.vertices);
			cmd.setSegments(this.segmentList);
			
			source.getCanvas().getCommandStack().execute(cmd);
		}		
		catch(e){
			console.log('from addline to add joint: error happend!');
		}
		finally{
			this.reset();
		}
		
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy.processStartToAddJoint<br>
	 * 函数功能：从点击开始到添加结点状态处理<br>
	 * 参数输入：args：object{source:port}<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	processStartToAddJoint : function(args){
		console.log("from start to add joint:" + args);
		if(args.source === args.target){
			this.reset();
		}
		try{
			var sourcePt = null,
				targetPt = null,
				mouseX   = null,
				mouseY   = null;
			var source   = null,
				target   = null;
	
			source			= args.source;
			sourcePt        = source.getAbsolutePosition();
			var targetConn 	= args.connection;	//目标端口
			var mouseX 		= args.x;			//鼠标点击x位置
			var mouseY 		= args.y;			//鼠标点击y位置
			var jointLoc    = this._calculateJointLocation(mouseX,mouseY,targetConn);
			
			if((sourcePt.x !== jointLoc.x) && (sourcePt.y !== jointLoc.y)){
				this.vertices.push(new draw2d.geo.Point(sourcePt.x,jointLoc.y));
			}
		    this.beeline.setEndPosition(jointLoc);
			
			var newVertices = new draw2d.util.ArrayList();
			this._toSegmentListByTargetPortLocation(this.vertices,jointLoc,this.segmentList,newVertices);
			this.vertices = newVertices;
			this.tempConnection.setVertices(this.vertices);
			
			var cmd = new Rainier.UI.V2.CommandAddJoint();
			cmd.setSourcePort(source);
			cmd.setTargetConnection(targetConn);
			cmd.setJointLocation(jointLoc);
			cmd.setVertices(this.vertices);
			cmd.setSegments(this.segmentList);
			
			source.getCanvas().getCommandStack().execute(cmd);
		}
		catch(e){
			console.log('from start to add joint: error happend!');
		}
		finally{
			this.reset();
		}
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy.processCancel<br>
	 * 函数功能：取消状态处理<br>
	 * 参数输入：args：object{source:port}<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	processCancel : function(args){
		console.log("from addline to cancel:" + args);
		this.reset();
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy.processStartToEnd<br>
	 * 函数功能：处理开始到结束状态<br>
	 * 参数输入：object:{x:x,y:y,source:this.sourcePort,target:this.targetPort}<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	processStartToEnd : function(args){
		console.log("from start to end:" + args);
		if(args.source === args.target){
			this.reset();
		}
		var sourcePt = null,
			targetPt = null,
			mouseX   = null,
			mouseY   = null;
		var source   = null,
			target   = null;
		if(args.source && args.target){
			sourcePt = args.source.getAbsolutePosition();
			targetPt = args.target.getAbsolutePosition();
			source	 = args.source;
			target	 = args.target;
		}
		if(args.x && args.y){
			mouseX = args.x;
			mouseY = args.y;
		}

		if(!(sourcePt && targetPt && mouseX && mouseY)){
			debugger;
		}
		if((sourcePt.x !== targetPt.x) && (sourcePt.y !== targetPt.y)){
			this.vertices.push(new draw2d.geo.Point(sourcePt.x,targetPt.y));
		}
	    this.beeline.setEndPosition(targetPt);
		
		var newVertices = new draw2d.util.ArrayList();
		this._toSegmentList(this.vertices,target,this.segmentList,newVertices);
		this.vertices = newVertices;
		this.tempConnection.setVertices(this.vertices);
		
        var request = new draw2d.command.CommandType(draw2d.command.CommandType.CONNECT);
        request.source = source;
        request.target = target;
        var command = null;
        if ((target instanceof draw2d.InputPort) || (target instanceof draw2d.HybridPort)) {
            command = target.createCommand(request);
        }

        if (command !== null) {
            command.setVertices(this.vertices);
            command.setSegments(this.segmentList);
            target.getCanvas().getCommandStack().execute(command);
        }
		
		console.log("from start to end------------>>:" + args);
		this.reset();
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy.processStartToAddLine<br>
	 * 函数功能：处理开始添加线段事件<br>
	 * 参数输入：object:{source:this.sourcePort,x:x,y:y}<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	processStartToAddLine : function(args){
		console.log("from start to addline:" + args);
        var canvas = args.source.getCanvas();
        this._addSegment(canvas);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy.processKeepAddLine<br>
	 * 函数功能：处理持续添加线段事件<br>
	 * 参数输入：object:{source:this.sourcePort,x:x,y:y}<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	processKeepAddLine : function(args){
		console.log("from addline to addline:" + args);
        var canvas = args.source.getCanvas();
        this._addSegment(canvas);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy.processAddLineToEnd<br>
	 * 函数功能：处理结束连接<br>
	 * 参数输入：object:{x:x,y:y,source:this.sourcePort,target:this.targetPort}<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	processAddLineToEnd : function(args){
		console.log("from addline to end:" + args);
		if(args.source === args.target){
			this.reset();
		}
		var source 	= args.source;	//源端口
		var target 	= args.target;	//目标端口
		var x      	= args.x;		//鼠标点击x位置
		var y 	   	= args.y;		//鼠标点击y位置

		var endPoint     = target.getAbsolutePosition();
        var last   = this.vertices.last();
        if (endPoint.x !== last.x &&　endPoint.y !== last.y) {            
            var x = last.x;
            var y = endPoint.y;
            var pre = this.vertices.get(this.vertices.getSize() - 2);
            if (pre && pre.x == last.x) {
                x = endPoint.x;
                y = last.y;
            }
            var centerPoint = new draw2d.geo.Point(x,y);
            this.vertices.add(centerPoint);
        }
        this.vertices.add(endPoint);

		//var newVertices = new draw2d.util.ArrayList();
		// this._toSegmentList(this.vertices,target,this.segmentList,newVertices);
		// this.vertices = newVertices;
		this.tempConnection.setVertices(this.vertices);

		for(var i=0,j=1; i < this.vertices.getSize()-1; i++,j++){
    	   var segment = {};
    	   var start = this.vertices.get(i);
    	   var end   = this.vertices.get(j);
    	   if(start.x === end.x){
    		   segment.start = start;
    		   segment.end   = end;
    		   segment.type  = "vertical";
    	   }
    	   if(start.y === end.y){
    		   segment.start = start;
    		   segment.end   = end;
    		   segment.type  = "horizontal";
    	   }
    	   this.segmentList.add(segment);
       }
		
        var request = new draw2d.command.CommandType(draw2d.command.CommandType.CONNECT);
        request.source = source;
        request.target = target;
        var command = null;
        if ((target instanceof draw2d.InputPort) || (target instanceof draw2d.HybridPort)) {
            command = target.createCommand(request);
        }

        if (command !== null) {
            command.setVertices(this.vertices);
            command.setSegments(this.segmentList);
            target.getCanvas().getCommandStack().execute(command);
        }
		
    	this.reset();
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy._calculateJointLocation<br>
	 * 函数功能：计算节点位置<br>
	 * 参数输入：mouseX:Number<br>
	 * 参数输入：mouseY:Number<br>
	 * 参数输入：targetConnection:draw2d.Connection<br>
	 * 函数返回：draw2d.geo.Point<br>
	 * 异常信息：<br>
	 */
	_calculateJointLocation:function(mouseX,mouseY,targetConnection){
		var vertices = targetConnection.getVertices();
		var segments = new draw2d.util.ArrayList();
		var jointLoc = {};
		var _this    = this;
		
		//如果鼠标点击位置接近拐点位置，则直接使用连续拐点作为几点位置
		vertices.each(function(i,vertex){
			if((Math.abs(vertex.x - mouseX) < _this.JOINT_SENSITIVITY_VALUE) && 
					(Math.abs(vertex.y - mouseY) < _this.JOINT_SENSITIVITY_VALUE)){
				jointLoc = new draw2d.geo.Point(vertex.x,vertex.y);
				jointLoc.x = vertex.x;
				jointLoc.y = vertex.y;
				jointLoc.offset = 0;
				return false;
			}
		});
		
		if(jointLoc.x){
			return jointLoc;
		}
		
		//在连接的线段上计算节点的合理位置
		for(var i=0,j=1; i < vertices.getSize()-1; i++,j++){
    	   var segment = {};
    	   var start = vertices.get(i);
    	   var end   = vertices.get(j);
    	   if(start.x === end.x){
    		   segment.start = start;
    		   segment.end   = end;
    		   segment.type  = "vertical";
    	   }
    	   if(start.y === end.y){
    		   segment.start = start;
    		   segment.end   = end;
    		   segment.type  = "horizontal";
    	   }
    	   segments.add(segment);
        }

		//var newPos = this.beeline.getEndPosition();
		segments.each(function(i,seg){
			var defaultValue = _this.ADJUST_VALUE;
			if(seg.type === 'horizontal'){
				if(Math.abs(seg.start.y - mouseY) < _this.JOINT_SENSITIVITY_VALUE){
					var jointX = parseInt(mouseX/defaultValue)*defaultValue;;
					jointLoc.x = jointX;
					jointLoc.y = seg.start.y;
					jointLoc.offset = Math.abs(seg.start.x - jointX);
					return false;
				}
			}
			if(seg.type === 'vertical'){
				if(Math.abs(seg.start.x - mouseX) < _this.JOINT_SENSITIVITY_VALUE){
					var jointY = parseInt(mouseY/defaultValue)*defaultValue;;
					jointLoc.x = seg.start.x;
					jointLoc.y = jointY;
					jointLoc.offset = Math.abs(seg.start.y - jointY);
					return false;
				}
			}
		});
		
		return jointLoc;
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy._toSegmentListByTargetPortLocation<br>
	 * 函数功能：将定点列表转换为线段表<br>
	 * 参数输入：vertices:draw2d.util.ArrayList<draw2d.Point><br>
	 * 参数输入：targetPortLoc:draw2d.geo.Point<br>
	 * 参数输出：segments:draw2d.util.ArrayList<{start:draw2d.Point,end:dra2d.Point,type:"horizontal/vertical"}><br>
	 * 参数输出：newVertices:draw2d.util.ArrayList<draw2d.Point><br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	_toSegmentListByTargetPortLocation: function(vertices,targetPortLoc,segments,newVertices){
	       var tempVertices = vertices.clone();
	       
	       var newPos = this.beeline.getEndPosition();
	       tempVertices.add(newPos);
	       
	       for(var i=0,j=1; i < tempVertices.getSize()-1; i++,j++){
	    	   var segment = {};
	    	   var start = tempVertices.get(i);
	    	   var end   = tempVertices.get(j);
	    	   if(start.x === end.x){
	    		   segment.start = start;
	    		   segment.end   = end;
	    		   segment.type  = "vertical";
	    	   }
	    	   if(start.y === end.y){
	    		   segment.start = start;
	    		   segment.end   = end;
	    		   segment.type  = "horizontal";
	    	   }
	    	   segments.add(segment);
	       }
	       
	       var lastSegment = segments.last();
	       var targetPos   = targetPortLoc;
	       
	       if(lastSegment.type === 'horizontal'){
	    	   lastSegment.end.x = targetPos.x;
	    	   lastSegment.end.y = targetPos.y;
	    	   lastSegment.start.y = targetPos.y;
	       }
	       
	       if(lastSegment.type === 'vertical'){
	    	   lastSegment.end.y = targetPos.y;
	    	   lastSegment.end.x = targetPos.x;
	    	   lastSegment.start.x = targetPos.x;
	       }

	       if(segments.getSize() > 1){
	           var preSegment  = segments.get(segments.getSize()-2);
	           preSegment.end = lastSegment.start.clone();    	   
	       }
	       
	       newVertices.clear();
	       segments.each(function(i,seg){
	    	   newVertices.add(seg.start);
	       });
	       newVertices.add(segments.last().end);

	},
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy._toSegmentList<br>
	 * 函数功能：将定点列表转换为线段表<br>
	 * 参数输入：vertices:draw2d.util.ArrayList<draw2d.Point><br>
	 * 参数输入：targetPort:draw2d.Port<br>
	 * 参数输出：segments:draw2d.util.ArrayList<{start:draw2d.Point,end:dra2d.Point,type:"horizontal/vertical"}><br>
	 * 参数输出：newVertices:draw2d.util.ArrayList<draw2d.Point><br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	_toSegmentList : function(vertices,targetPort,segments,newVertices){
       
       var tempVertices = vertices.clone();
       
       var newPos = this.beeline.getEndPosition();
       tempVertices.add(newPos);
       
       for(var i=0,j=1; i < tempVertices.getSize()-1; i++,j++){
    	   var segment = {};
    	   var start = tempVertices.get(i);
    	   var end   = tempVertices.get(j);
    	   if(start.x === end.x){
    		   segment.start = start;
    		   segment.end   = end;
    		   segment.type  = "vertical";
    	   }
    	   if(start.y === end.y){
    		   segment.start = start;
    		   segment.end   = end;
    		   segment.type  = "horizontal";
    	   }
    	   segments.add(segment);
       }
       
       var lastSegment = segments.last();
       var targetPos   = this.targetPort.getAbsolutePosition();
       
       if(lastSegment.type === 'horizontal'){
    	   lastSegment.end.x = targetPos.x;
    	   lastSegment.end.y = targetPos.y;
    	   lastSegment.start.y = targetPos.y;
       }
       
       if(lastSegment.type === 'vertical'){
    	   lastSegment.end.y = targetPos.y;
    	   lastSegment.end.x = targetPos.x;
    	   lastSegment.start.x = targetPos.x;
       }

       if(segments.getSize() > 1){
           var preSegment  = segments.get(segments.getSize()-2);
           preSegment.end = lastSegment.start.clone();    	   
       }
       newVertices.clear();
       segments.each(function(i,seg){
    	   newVertices.add(seg.start);
       });
       newVertices.add(segments.last().end);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy._addSegment<br>
	 * 函数功能：添加线段<br>
	 * 参数输入：canvas:draw2d.Canvas<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	_addSegment : function(canvas){
        var newPos = this.beeline.getEndPosition();
        
        var x = newPos.x;
        var y = newPos.y;
        var _x= (x % this.ADJUST_VALUE);
        var _y= (y % this.ADJUST_VALUE);
        
        if(_x > this.ADJUST_VALUE/2){
        	x = (x - _x) + this.ADJUST_VALUE;
        }else{
        	x = (x - _x);
        }
        
        if(_y > this.ADJUST_VALUE/2){
        	y = (y - _y) + this.ADJUST_VALUE;
        }else{
        	y = (y - _y);
        }
        
        newPos.x = x;
        newPos.y = y;
        this.beeline.setEndPosition(newPos);
        
        this.vertices.add(newPos);
        this.beeline.setStartPosition(this.beeline.getEndPosition());
        this.tempConnection.setVertices(this.vertices);
        if(this.pulse!==null) {
            this.pulse.remove();
            this.pulse = null;
        }
        this.ripple(newPos.x, newPos.y, 0);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy.reset<br>
	 * 函数功能：重置编辑策略<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	reset : function(){
        if (this.beeline!==null){
            this.beeline.hide();
            this.tempConnection.hide();
            this.beeline = null;
            this.port1=null;
            this.vertices.clear();
            if(this.pulse!=null) {
                this.pulse.remove();
                this.pulse=null;
            }
        }
    	this.sourcePort = null;
    	this.targetPort = null;
    	this.segmentList.clear();
    	this.runState.current = 'none'
	},
	
    /**
     * @method
     * Callback if the user press a key down
     * 
     * @param {draw2d.Canvas} canvas the related canvas
     * @param {Number} keyCode the pressed key
     * @param {Boolean} shiftKey true if the shift key has been pressed during this event
     * @param {Boolean} ctrlKey true if the ctrl key has been pressed during the event
     * @private
     **/
    onKeyDown: function(canvas, keyCode, shiftKey, ctrlKey){
    	//if((keyCode === 27) && (this.runState.current !== 'none')){
    	if(keyCode === 27){
    		this.runState.onEventCancel();
    	}
    	this._super(canvas, keyCode, shiftKey, ctrlKey);
    },
    
    /**
	 * 函数名称：Rainier.UI.V2.OrthogonalConnectionCreatePolicy.createConnection<br>
	 * 函数功能：鼠标弹起<br>
	 * 函数返回：connection:draw2d.connection<br>
     * @param {draw2d.Canvas} canvas
     * @param {Number} x the x-coordinate of the mouse event
     * @param {Number} y the y-coordinate of the mouse event
     * @param {Boolean} shiftKey true if the shift key has been pressed during this event
     * @param {Boolean} ctrlKey true if the ctrl key has been pressed during the event
     * @template
     */
    _onClick: function(figure, x, y, shiftKey, ctrlKey){
    	if(this.beeline){
        	if(figure && figure instanceof draw2d.Connection){
        		var newConnProperty = {};
        		newConnProperty.sourcePort 		= this.port1;
        		newConnProperty.vertices 		= this.vertices;
        		var cmd = new Rainier.UI.V2.CommandAddJoint(figure,x,y,newConnProperty);  
    			if(cmd){
    				var canvas = figure.getCanvas();
    				canvas.getCommandStack().execute(cmd);
    				var jointPortModel 	  = cmd.newJointModel.getHybridPorts().get(0);
    				var jointPortEditPart = canvas.context.findEditPartByModel(jointPortModel);
    				var jointPortFigure   = jointPortEditPart.getFigure();
    				this._super(jointPortFigure, x, y, shiftKey, ctrlKey);
    			}			
            }
    	}
    	this._super(figure, x, y, shiftKey, ctrlKey);
    },
    
    /**
     * @method
     * Called by the canvas if the user click on a figure.
     *
     * @param {draw2d.Figure} the figure under the click event. Can be null
     * @param {Number} x the x coordinate of the mouse during the click event
     * @param {Number} y the y coordinate of the mouse during the click event
     * @param {Boolean} shiftKey true if the shift key has been pressed during this event
     * @param {Boolean} ctrlKey true if the ctrl key has been pressed during the event
     *
     * @since 6.1.0
     *
     * @template
     */
    onClick: function(figure, x, y, shiftKey, ctrlKey){
    	
    	if(!figure && this.runState.current === 'none'){
    		return;
    	}
    	
    	if(figure && !(figure instanceof draw2d.Port) && this.runState.current === 'none'){
    		return;
    	}
    	
    	var canvas = null; 
    	var clickedFigure = null;
    	    	
    	if(figure){

    		var activeEditor   = app.getContext().getActiveEditor();
    		var status  = activeEditor.getRunStatus();
    		
    		if(status){
    			return;
    		}
    		canvas   		= figure.getCanvas();
        	
    		var rootEditPart = canvas.context.getRootEditPart();
    		if(rootEditPart.getCreateState()){
        		return;
    		}
    		clickedFigure   = canvas.getBestFigure(x, y);    		
    	}
    	
    	//当前选择了一个输入端口并且源端口为null的情况下，表示从输入端口创建连接，这种情况下什么都不做。
    	if((clickedFigure instanceof draw2d.InputPort) && (this.sourcePort === null)){
    		return;
    	}
		
    	var defaultValue 	= this.ADJUST_VALUE;
    	var remainderX 		= x% defaultValue;
    	var remainderY 		= y% defaultValue;
	   	if(remainderX !== 0){
			x = x - parseFloat((remainderX > defaultValue/2)?(remainderX - defaultValue):remainderX);
		}
		if(remainderY !== 0){
			y = y - parseFloat((remainderY > defaultValue/2)?(remainderY - defaultValue):remainderY);
		}
    	
    	//进入开始连接状态
    	if((this.sourcePort === null) && (this.targetPort === null) && 
    			((clickedFigure instanceof draw2d.HybridPort) || (clickedFigure instanceof draw2d.OutputPort))){
    		this.sourcePort = clickedFigure;
    		this.runState.current = 'start';
    		this.runState.startup();  
    		this.processStartup({source:this.sourcePort})
    		return;
    	}
    	
    	//进入添加线段或结束连接状态
    	if((this.sourcePort !== null) && (this.targetPort === null) && 
    			((clickedFigure instanceof draw2d.HybridPort) || (clickedFigure instanceof draw2d.InputPort))){
    		this.targetPort = clickedFigure;
    		if(this.runState.current === "start"){
    			this.runState.EventStartToEnd({x:x,y:y,source:this.sourcePort,target:this.targetPort});    			
    		}
    		if(this.runState.current === "addline"){
    			this.runState.EventAddLineToEnd({x:x,y:y,source:this.sourcePort,target:this.targetPort});    			
    		}
    		return;
    	}

    	//从开始状态进入创建节点状态
    	// if((this.runState.current === "start") && (figure instanceof draw2d.Connection)){
    	// 	this.runState.EventStartToAddJoint({source:this.sourcePort,connection:figure,x:x,y:y});
    	// 	return;
    	// }
    	
    	// //从添加连线状态进入创建节点状态
    	// if((this.runState.current === "addline") && (figure instanceof draw2d.Connection)){
    	// 	this.runState.EventAddLineToAddJoint({source:this.sourcePort,connection:figure,x:x,y:y});
    	// 	return;
    	// }
    	
    	//从开始创建连接状态切换到添加线段状态
		if(this.runState.current === "start"){
			this.runState.EventStartToAddLine({source:this.sourcePort,x:x,y:y});  
			return;
		}
		
		//保持添加线段状态
		if(this.runState.current === "addline"){
			this.runState.EventAddLineToAddLine({source:this.sourcePort,x:x,y:y});    
			return;
		}
    },
    
    /**
     * @method
     * Called by the canvas if the user click on a figure.
     *
     * @param {draw2d.Figure} the figure under the click event. Can be null
     * @param {Number} x the x coordinate of the mouse during the click event
     * @param {Number} y the y coordinate of the mouse during the click event
     * @param {Boolean} shiftKey true if the shift key has been pressed during this event
     * @param {Boolean} ctrlKey true if the ctrl key has been pressed during the event
     *
     * @since 6.1.0
     *
     * @template
     */
    _onClick: function(figure, x, y, shiftKey, ctrlKey)
    {
        var UP   = draw2d.geo.Rectangle.DIRECTION_UP;
        var RIGHT= draw2d.geo.Rectangle.DIRECTION_RIGHT;
        var DOWN = draw2d.geo.Rectangle.DIRECTION_DOWN;
        var LEFT = draw2d.geo.Rectangle.DIRECTION_LEFT;

        var _this = this;
        var port = figure;// .getCanvas().getBestFigure(x, y);

        // nothing to do
        if(port === null && this.port1 === null){
            return;
        }

        // nothing found at all
        //
        if(port===null){
            var canvas = this.port1.getCanvas();
            var newPos = this.beeline.getEndPosition();
            this.vertices.add(newPos);
            this.beeline.setStartPosition(this.beeline.getEndPosition());
            this.tempConnection.setVertices(this.vertices);
            if(this.pulse!==null) {
                this.pulse.remove();
                this.pulse = null;
            }
            this.ripple(newPos.x, newPos.y, 0);
            return;
        }

        // we just considering ports
        //
        if(!(port instanceof draw2d.Port)){
            return;
        }

        // start connection create by selection the start port
        //
        if(this.port1===null){
            var canvas = port.getCanvas();
            this.port1 = port;
            this.vertices.add(port.getAbsolutePosition());
            this.beeline = new draw2d.shape.basic.Line({
                start: this.port1.getAbsolutePosition(),
                end: this.port1.getAbsolutePosition(),
                dasharray:"- ",
                color:"#2C70FF"
            });

            this.beeline.hide= function(){
                _this.beeline.setCanvas(null);
            };

            this.beeline.show= function(canvas){
                _this.beeline.setCanvas(canvas);
                _this.beeline.shape.toFront();
            };
            this.beeline.show(canvas);

            this.tempConnection = new draw2d.shape.basic.PolyLine({
                start: this.port1.getAbsolutePosition(),
                end: this.port1.getAbsolutePosition(),
                stroke:2,
                color:"#2C70FF"
            });

            this.tempConnection.hide= function(){
                _this.tempConnection.setCanvas(null);
            };

            this.tempConnection.show= function(canvas){
                _this.tempConnection.setCanvas(canvas);
                _this.tempConnection.shape.toFront();
            };
            this.tempConnection.show(canvas);
            this.tempConnection.setVertices([this.port1.getAbsolutePosition(),this.port1.getAbsolutePosition()]);

            var a= function() {
                _this.tempConnection.shape.animate({"stroke-width" : 2}, 800, b);
            };
            var b=function() {
                _this.tempConnection.shape.animate({"stroke-width":1}, 800, a);
            };
            a();

            canvas.paper.setStart();

            // delete the previews puls if the user press twice on the starting port
            //
            if(this.pulse!==null) {
                this.pulse.remove();
                this.pulse = null;
            }

            var pos = port.getAbsolutePosition();
            this.ripple(pos.x, pos.y, 1);
            this.pulse = canvas.paper.setFinish();
        }
        else {
            var possibleTarget = port.delegateTarget(this.port1);

            if (!(possibleTarget instanceof draw2d.Port)) {
                return; // silently
            }

            // check whenever the target port allows a connection
            //
            var request = new draw2d.command.CommandType(draw2d.command.CommandType.CONNECT);
            request.source = this.port1;
            request.target = port;
            var command = null;
            if (this.port1 instanceof draw2d.InputPort) {
                command = this.port1.createCommand(request);
            }
            else {
                command = port.createCommand(request);
            }

            if (command !== null) {
                var connection = this.createConnection();
                command.setConnection(connection);
                port.getCanvas().getCommandStack().execute(command);

                this.beeline.hide();
                this.tempConnection.hide();
                if (this.pulse !== null) {
                    this.pulse.remove();
                    this.pulse = null;
                }
                this.beeline = null;
                this.port1 = null;

                // use the default routing if the user didn't add some
                // vertices
                if(this.vertices.getSize()<=2){
                    return;
                }

                var MINDIST = command.getConnection().getRouter().MINDIST;
                var beforeVertex = this.vertices.get(this.vertices.getSize()-2);
                var lastVertex   = this.vertices.last();
                var portPos      = port.getAbsolutePosition();
                var lastSegmentDir = UP;
                if(lastVertex.x === beforeVertex.x){
                    lastSegmentDir = lastVertex.y< beforeVertex.y ? UP : DOWN;
                }
                else{
                    lastSegmentDir = lastVertex.x< beforeVertex.x ? LEFT : RIGHT;
                }

                // CALCULATE THE LAST MILE OF THE CONNECTION
                //
                // ensure that we have a valid "manhattan style" connection.
                // We must add or adjust some points or segments.
                //
                // The code below creates and adjust the points in that way that the
                // DOTTED line is the calculated part to the user defined vertices.
                // ==================================
                //
                var _ddir = port.getConnectionDirection(this.port1);
                switch(_ddir){
                    case UP:
                        switch(lastSegmentDir){
                            case UP:
                                //       o..................o lastVertex
                                //       |         .        |
                                //       |         .        |
                                //       |    +----O----+   |
                                // ------o    | portPos |   o------------
                                //            |         |      beforeVertex
                                //            +---------+
                                //
                                if(lastVertex.y<(portPos.y-MINDIST)) {
                                    this.vertices.add(new draw2d.geo.Point(portPos.x, lastVertex.y));
                                    this.vertices.add(portPos);
                                }
                                //        ...................
                                //        .        .        .
                                //        .   +----O----+   .
                                //        o   | portPos |   o lastVertex
                                //        |   |         |   |
                                //        |   +---------+   |
                                // -------o                 o------------
                                //                            beforeVertex
                                //
                                else{
                                    lastVertex.y = portPos.y-MINDIST;
                                    this.vertices.add(new draw2d.geo.Point(portPos.x, lastVertex.y));
                                    this.vertices.add(portPos);
                                }
                                break;
                            case RIGHT:
                                //  ..............................
                                //  .                   .        .
                                //  .                   .        .
                                //  o------->o     +----O----+   o---------------->O
                                //  |              | portPos |   | beforeVertex    lastVertex
                                //  |              |         |   |
                                //  |              +---------+
                                if(lastVertex.y>(portPos.y-MINDIST)){
                                    beforeVertex.y = portPos.y-MINDIST;
                                    lastVertex.x = portPos.x;
                                    lastVertex.y = beforeVertex.y;
                                    this.vertices.add(portPos);
                                }
                                //
                                //                                beforeVertex   lastVertex
                                // o---------->o..................o------------->O
                                // |                     .        |
                                // |                +----O----+   |
                                // |                | portPos |   |
                                // |                |         |   |
                                //                  +---------+
                                else{
                                    lastVertex.x = portPos.x;
                                    this.vertices.add(portPos);
                                }
                                break;
                            case DOWN:
                                //                           beforeVertex
                                // ------o..................o------------
                                //       |         .        |
                                //       |         .        |
                                //       V    +----O----+   V
                                //       o    | portPos |   o lastVertex
                                //            |         |
                                //            +---------+
                                //
                                if(lastVertex.y<(portPos.y-MINDIST)) {
                                    beforeVertex.x = portPos.x;
                                    lastVertex.setPosition(portPos);
                                }
                                //        ...................
                                //        .        .        .
                                //        .   +----O----+   . beforeVertex
                                // -------o   | portPos |   o------------
                                //        |   |         |   |
                                //        V   +---------+   V
                                //        o                 o
                                //                            lastVertex
                                //
                                else{
                                    lastVertex.y = portPos.y-MINDIST;
                                    this.vertices.add(new draw2d.geo.Point(portPos.x,lastVertex.y ));
                                    this.vertices.add(portPos);
                                }
                                break;
                            case LEFT:
                                //           ..................................
                                //           .         .                       .
                                //           .         .                       .
                                // o<--------o    +----O----+   o<-------------O beforeVertex
                                //           |    | portPos |    lastVertex    |
                                //           |    |         |                  |
                                //                +---------+
                                if(lastVertex.y>(portPos.y-MINDIST)){
                                    beforeVertex.y = portPos.y-MINDIST;
                                    lastVertex.x = portPos.x;
                                    lastVertex.y = beforeVertex.y;
                                    this.vertices.add(portPos);
                                }
                                //             |                               |
                                //             |                               |
                                //   o<--------o................o<-------------O
                                //                      .        lastVertex     beforeVertex
                                //                 +----O----+
                                //                 | portPos |
                                //                 |         |
                                //                 +---------+
                                else{
                                    lastVertex.x = portPos.x;
                                    this.vertices.add(portPos);
                                }
                                break;
                        }
                        break;
                    case RIGHT:
                        switch(lastSegmentDir){
                            case UP:
                                //                    o lastVertex
                                //                    |
                                //                    |
                                //  ------------------o beforeVertex
                                //                    .
                                //  +----------+      .
                                //  |          |      .
                                //  |  portPos O.......
                                //  |          |      .
                                //  +----------+      .
                                //                    o lastVertex
                                //                    |
                                //                    |
                                //   -----------------o beforeVertex
                                //
                                if(lastVertex.x > (portPos.x+MINDIST)){
                                    lastVertex.y = portPos.y;
                                    this.vertices.add(portPos);
                                }
                                //        lastVertex
                                //      o...............
                                //      |              .
                                //      |              .
                                //  ----o beforeVertex .
                                //                     .
                                //  +----------+       .
                                //  |          |       .
                                //  |  portPos O........
                                //  |          |       .
                                //  +----------+       .
                                //      o...............
                                //      | lastVertex
                                //      |
                                //------o
                                //        beforeVertex
                                //
                                //
                                else{
                                    this.vertices.add(new draw2d.geo.Point(portPos.x+MINDIST, lastVertex.y));
                                    this.vertices.add(new draw2d.geo.Point(portPos.x+MINDIST, portPos.y));
                                    this.vertices.add(portPos);
                                }
                                break;
                            case RIGHT:
                                //    beforeVertex     lastVertex
                                //    o-------------->o
                                //                    .
                                //  +----------+      .
                                //  |          |      .
                                //  |  portPos O.......
                                //  |          |      .
                                //  +----------+      .
                                //                    .
                                //    o-------------->o
                                //    beforeVertex     lastVertex
                                //
                                if(lastVertex.x > (portPos.x+MINDIST)){
                                    this.vertices.add(new draw2d.geo.Point(lastVertex.x, portPos.y));
                                    this.vertices.add(portPos);
                                }
                                // beforeVertex  lastVertex
                                // o------------>o.........
                                //                         .
                                //       +----------+      .
                                //       |          |      .
                                //       |  portPos O.......
                                //       |          |      .
                                //       +----------+      .
                                //                         .
                                //  o----------->o..........
                                // beforeVertex  lastVertex
                                //
                                else{
                                    lastVertex.x =  portPos.x+MINDIST;
                                    this.vertices.add(new draw2d.geo.Point(lastVertex.x, portPos.y));
                                    this.vertices.add(portPos);
                                }
                                break;
                            case DOWN:
                                //    ----------------o beforeVertex
                                //                    |
                                //                    |
                                //                    o lastVertex
                                //                    .
                                //  +----------+      .
                                //  |          |      .
                                //  |  portPos O.......
                                //  |          |      .
                                //  +----------+      .
                                //                    .
                                //      --------------o beforeVertex
                                //                    |
                                //                    |
                                //                    o lastVertex
                                //
                                if(lastVertex.x > (portPos.x+MINDIST)){
                                    lastVertex.y = portPos.y;
                                    this.vertices.add(portPos);
                                }
                                //    -----o beforeVertex
                                //         |
                                //         | lastVertex
                                //         o...........
                                //                    .
                                //  +----------+      .
                                //  |          |      .
                                //  |  portPos O.......
                                //  |          |      .
                                //  +----------+      .
                                //                    .
                                // ----o beforeVertex .
                                //     |              .
                                //     | lastVertex   .
                                //     o...............
                                //
                                else{
                                    this.vertices.add(new draw2d.geo.Point(portPos.x+MINDIST, lastVertex.y));
                                    this.vertices.add(new draw2d.geo.Point(portPos.x+MINDIST, portPos.y));
                                    this.vertices.add(portPos);
                                }
                                break;
                            case LEFT:
                                //                lastVertex      beforeVertex
                                //               o<--------------o
                                //               .
                                //  +----------+ .
                                //  |          | .
                                //  |  portPos O..
                                //  |          | .
                                //  +----------+ .
                                //               .
                                //               o<--------------o
                                //                lastVertex      beforeVertex
                                //
                                if(lastVertex.x > (portPos.x+MINDIST)){
                                    this.vertices.add(new draw2d.geo.Point(lastVertex.x, portPos.y));
                                    this.vertices.add(portPos);
                                }
                                // lastVertex                beforeVertex
                                // o<-----------------------o
                                //                      .
                                //       +----------+   .
                                //       |          |   .
                                //       |  portPos O....
                                //       |          |   .
                                //       +----------+   .
                                //                      .
                                //  o<----------------------o
                                //  lastVertex               beforeVertex
                                //
                                else{
                                    lastVertex.x =  portPos.x+MINDIST;
                                    this.vertices.add(new draw2d.geo.Point(lastVertex.x, portPos.y));
                                    this.vertices.add(portPos);
                                }
                                break;
                        }
                        break;
                    case DOWN:
                        switch(lastSegmentDir){
                            case UP:
                                //       o                  o lastVertex
                                //       |                  |
                                //       |                  |
                                //       |    +---------+   |
                                // ------o    |         |   o------------
                                //       .    | portPos |   . beforeVertex
                                //       .    +----O----+   .
                                //       .         .        .
                                //       ....................
                                //
                                if(lastVertex.y<(portPos.y+MINDIST)) {
                                    lastVertex.y = portPos.y+MINDIST;
                                    this.vertices.add(new draw2d.geo.Point(portPos.x, lastVertex.y));
                                    this.vertices.add(portPos);
                                }
                                //            +---------+
                                //            |         |
                                //            | portPos |
                                //            +----O----+
                                //                 .
                                //        o.................o lastVertex
                                //        |                 |
                                //        |                 |
                                // -------o                 o------------
                                //                            beforeVertex
                                //
                                else{
                                    lastVertex.x   = portPos.x;
                                    lastVertex.y   = portPos.y;
                                    beforeVertex.x = portPos.x;
                                }
                                break;
                            case RIGHT:
                                //                 +---------+
                                //                 |         |
                                //                 | portPos |
                                //  o------->o     +----O----+    o--------------->O
                                //  |        .          .         | beforeVertex   . lastVertex
                                //  |        .....................|.................
                                //  |
                                //
                                //
                                if(lastVertex.y<(portPos.y+MINDIST)){
                                    this.vertices.add(new draw2d.geo.Point(lastVertex.x, portPos.y+MINDIST));
                                    this.vertices.add(new draw2d.geo.Point(portPos.x, portPos.y+MINDIST));
                                    this.vertices.add(portPos);
                                }
                                //                  +---------+
                                //                  |         |
                                //                  | portPos |
                                //                  +----O----+
                                //                       .
                                //             ...................................
                                //             .                    beforeVertex . lastVertex
                                // o---------->o                  o------------->O
                                // |                              |
                                // |                              |
                                //
                                else{
                                    lastVertex.x = portPos.x;
                                    this.vertices.add(portPos);
                                }
                                break;
                            case DOWN:
                                //                           beforeVertex
                                // ------o                  o------------
                                //       |                  |
                                //       |                  |
                                //       V    +---------+   V
                                //       o    |         |   o lastVertex
                                //       .    | portPos |   .
                                //       .    +----O----+   .
                                //       .         .        .
                                //       ....................
                                //
                                if(lastVertex.y<(portPos.y+MINDIST)) {
                                    lastVertex.y = portPos.y+MINDIST;
                                    this.vertices.add(new draw2d.geo.Point(portPos.x,lastVertex.y ));
                                    this.vertices.add(portPos);
                                }
                                //
                                //            +---------+     beforeVertex
                                // -------o   | portPos |   o------------
                                //        |   |         |   |
                                //        V   +----O----+   V
                                //        o        .        o
                                //        ..................  lastVertex
                                //
                                else{
                                    this.vertices.add(new draw2d.geo.Point(portPos.x,lastVertex.y ));
                                    this.vertices.add(portPos);
                                }
                                break;
                            case LEFT:
                                //
                                // o<--------o    +---------+   o<-------------O beforeVertex
                                // .         |    |         |   . lastVertex   |
                                // .         |    | portPos |   .              |
                                // .              +----O----+   .
                                // .                   .        .
                                // ..............................
                                //
                                if(lastVertex.y<(portPos.y-MINDIST)){
                                    beforeVertex.y = portPos.y-MINDIST;
                                    lastVertex.x = portPos.x;
                                    lastVertex.y = beforeVertex.y;
                                    this.vertices.add(portPos);
                                }
                                //
                                //                +---------+
                                //           |    |         |               |
                                //           |    | portPos |               |
                                //           |    +----O----+               |
                                //           |         .                    |
                                // o<--------o...................o<---------o
                                //
                                else{
                                    lastVertex.x = portPos.x;
                                    this.vertices.add(portPos);
                                }
                                break;
                        }
                        break;
                    case LEFT:
                        switch(lastSegmentDir){
                            case UP:
                                //    ................o lastVertex
                                //    .               |
                                //    .               |
                                //  --.---------------o beforeVertex
                                //    .
                                //    .   +----------+
                                //    .   |          |
                                //    ....o  portPos |
                                //    .   |          |
                                //    .   +----------+
                                //    .
                                //    ................o lastVertex
                                //                    |
                                //                    |
                                //   -----------------o beforeVertex
                                //
                                if(lastVertex.x >= (portPos.x-MINDIST)){
                                    this.vertices.add(new draw2d.geo.Point(portPos.x-MINDIST, lastVertex.y));
                                    this.vertices.add(new draw2d.geo.Point(portPos.x-MINDIST, portPos.y));
                                    this.vertices.add(portPos);
                                }
                               //
                                //            +----------+
                                //            |          |
                                //      ......o  portPos |
                                //      .     |          |
                                //      .     +----------+
                                //      o
                                //      | lastVertex
                                //      |
                                //------o
                                //        beforeVertex
                                //
                                //
                                else if(lastVertex.y > portPos.y && lastVertex.x < (portPos.x-MINDIST)){
                                    lastVertex.y = portPos.y;
                                    this.vertices.add(portPos);
                                }
                                //          lastVertex
                                //      o..
                                //      | .
                                //      | .
                                //  ----o .   beforeVertex
                                //        .
                                //        .   +----------+
                                //        .   |          |
                                //        ....o  portPos |
                                //            |          |
                                //            +----------+
                                //
                                else{
                                    this.vertices.add(new draw2d.geo.Point(portPos.x-MINDIST, lastVertex.y));
                                    this.vertices.add(new draw2d.geo.Point(portPos.x-MINDIST, portPos.y));
                                    this.vertices.add(portPos);
                                }
                                break;
                            case RIGHT:
                                //    beforeVertex     lastVertex
                                //    o-------------->o
                                //                    .
                                // ....................
                                // .
                                // .      +----------+
                                // .      |          |
                                // .......o  portPos |
                                //        |          |
                                //        +----------+
                                //
                                if(lastVertex.y<portPos.y && lastVertex.x > (portPos.x-MINDIST)){
                                    var center = portPos.y-(portPos.y-lastVertex.y)/2;
                                    this.vertices.add(new draw2d.geo.Point(lastVertex.x, center));
                                    this.vertices.add(new draw2d.geo.Point(portPos.x-MINDIST, center));
                                    this.vertices.add(new draw2d.geo.Point(portPos.x-MINDIST, portPos.y));
                                    this.vertices.add(portPos);
                                }
                                //        +----------+
                                //        |          |
                                // .......o  portPos |
                                // .      |          |
                                // .      +----------+
                                // .
                                // ....................
                                //                    .
                                //    o-------------->o
                                //    beforeVertex     lastVertex
                                //
                                else if(lastVertex.y>portPos.y && lastVertex.x > (portPos.x-MINDIST)){
                                    var center = portPos.y+(lastVertex.y-portPos.y)/2;
                                    this.vertices.add(new draw2d.geo.Point(lastVertex.x, center));
                                    this.vertices.add(new draw2d.geo.Point(portPos.x-MINDIST, center));
                                    this.vertices.add(new draw2d.geo.Point(portPos.x-MINDIST, portPos.y));
                                    this.vertices.add(portPos);
                                }
                                // beforeVertex  lastVertex
                                // o------------>o
                                //               .
                                //               .   +----------+
                                //               .   |          |
                                //               ....o  portPos |
                                //               .   |          |
                                //               .   +----------+
                                //               .
                                //  o----------->o
                                // beforeVertex  lastVertex
                                //
                                else{
                                    this.vertices.add(new draw2d.geo.Point(lastVertex.x, portPos.y));
                                    this.vertices.add(portPos);
                                }
                                break;
                            case DOWN:
                                //         -----------o beforeVertex
                                //                    |
                                //                    |
                                //                    V
                                //    ................o lastVertex
                                //    .
                                //    .       +----------+
                                //    .       |          |
                                //    ........o portPos  |
                                //    .       |          |
                                //    .       +----------+
                                //    .
                                //    .        --------o beforeVertex
                                //    .                |
                                //    .                |
                                //    .                V
                                //    .................o lastVertex
                                //
                                if(lastVertex.x >= (portPos.x-MINDIST)){
                                    this.vertices.add(new draw2d.geo.Point(portPos.x-MINDIST, lastVertex.y));
                                    this.vertices.add(new draw2d.geo.Point(portPos.x-MINDIST, portPos.y));
                                    this.vertices.add(portPos);
                                }
                                //    -----o beforeVertex
                                //         |
                                //         |
                                //         o lastVertex
                                //         .
                                //         .       +----------+
                                //         .       |          |
                                //         ........o portPos  |
                                //             .   |          |
                                //             .   +----------+
                                // beforeVertex.
                                // ------------o
                                //             |
                                //             |
                                // lastVertex  o
                                //
                                else{
                                    lastVertex.y=portPos.y;
                                    this.vertices.add(portPos);
                                }
                                break;
                            case LEFT:
                                //   lastVertex      beforeVertex
                                //    o<--------------o
                                //    .
                                //    .       +----------+
                                //    .       |          |
                                //    ....... o portPos  |
                                //    .       |          |
                                //    .       +----------+
                                //    .
                                //    o<--------------o
                                //    lastVertex      beforeVertex
                                //
                                if(lastVertex.x < (portPos.x-MINDIST)){
                                    this.vertices.add(new draw2d.geo.Point(lastVertex.x, portPos.y));
                                    this.vertices.add(portPos);
                                }
                                //         lastVertex                beforeVertex
                                //  .......o<-----------------------o
                                //  .
                                //  .    +----------+
                                //  .    |          |
                                //  .....o portPos  |
                                //  .    |          |
                                //  .    +----------+
                                //  .
                                //  ........o<----------------------o
                                //         lastVertex               beforeVertex
                                //
                                else{
                                    lastVertex.x =  portPos.x-MINDIST;
                                    this.vertices.add(new draw2d.geo.Point(lastVertex.x, portPos.y));
                                    this.vertices.add(portPos);
                                }
                            break;
                        }
                    break;
                }

                if(this.vertices.getSize()>3) {
                    connection._routingMetaData.routedByUserInteraction = true;
                    connection.setVertices(this.vertices);
                }
                this.vertices.clear();
            }
        }
    },
});